home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / doom / quake2.zip / QJOE19.ZIP / ITEMS.QC < prev    next >
Text File  |  1996-08-20  |  30KB  |  1,386 lines

  1. void() W_SetCurrentAmmo;
  2. void() RestoreBodyB;
  3. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  4. BE .8 .3 .4 IN COLOR */
  5.  
  6.  
  7. void() SUB_regen =
  8. {
  9.     self.model = self.mdl;          // restore original model
  10.     self.solid = SOLID_TRIGGER;     // allow it to be touched again
  11.     sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  12.     setorigin (self, self.origin);
  13. };
  14.  
  15.  
  16.  
  17. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  18. prints a warning message when spawned
  19. */
  20. void() noclass =
  21. {
  22.     dprint ("noclass spawned at");
  23.     dprint (vtos(self.origin));
  24.     dprint ("\n");
  25.     remove (self);
  26. };
  27.  
  28.  
  29.  
  30. /*
  31. ============
  32. PlaceItem
  33.  
  34. plants the object on the floor
  35. ============
  36. */
  37. void() PlaceItem =
  38. {
  39.     local float     oldz;
  40.  
  41.     self.mdl = self.model;          // so it can be restored on respawn
  42.     self.flags = FL_ITEM;           // make extra wide
  43.     self.solid = SOLID_TRIGGER;
  44.     self.movetype = MOVETYPE_TOSS;  
  45.     self.velocity = '0 0 0';
  46.     self.origin_z = self.origin_z + 6;
  47.     oldz = self.origin_z;
  48.     if (!droptofloor())
  49.     {
  50.         dprint ("Bonus item fell out of level at ");
  51.         dprint (vtos(self.origin));
  52.         dprint ("\n");
  53.         remove(self);
  54.         return;
  55.     }
  56. };
  57.  
  58. /*
  59. ============
  60. StartItem
  61.  
  62. Sets the clipping size and plants the object on the floor
  63. ============
  64. */
  65. void() StartItem =
  66. {
  67.     self.nextthink = time + 0.2;    // items start after other solids
  68.     self.think = PlaceItem;
  69. };
  70.  
  71. /*
  72. =========================================================================
  73.  
  74. HEALTH BOX
  75.  
  76. =========================================================================
  77. */
  78. //
  79. // T_Heal: add health to an entity, limiting health to max_health
  80. // "ignore" will ignore max_health limit
  81. //
  82. float (entity e, float healamount, float ignore) T_Heal =
  83. {
  84.     if (e.health <= 0)
  85.         return 0;
  86.     if ((!ignore) && (e.health >= other.max_health))
  87.         return 0;
  88.     healamount = ceil(healamount);
  89.  
  90.     e.health = e.health + healamount;
  91.     if ((!ignore) && (e.health >= other.max_health))
  92.         e.health = other.max_health;
  93.         
  94.     if (e.health > 250)
  95.         e.health = 250;
  96.     return 1;
  97. };
  98.  
  99. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  100. Health box. Normally gives 25 points.
  101. Rotten box heals 5-10 points,
  102. megahealth will add 100 health, then 
  103. rot you down to your maximum health limit, 
  104. one point per second.
  105. */
  106.  
  107. float   H_ROTTEN = 1;
  108. float   H_MEGA = 2;
  109. .float  healamount, healtype;
  110. void() health_touch;
  111. void() item_megahealth_rot;
  112.  
  113. void() item_health =
  114. {       
  115.     self.touch = health_touch;
  116.  
  117.     if (self.spawnflags & H_ROTTEN)
  118.     {
  119.         precache_model("maps/b_bh10.bsp");
  120.  
  121.         precache_sound("items/r_item1.wav");
  122.         setmodel(self, "maps/b_bh10.bsp");
  123.         self.noise = "items/r_item1.wav";
  124.         self.healamount = 15;
  125.         self.healtype = 0;
  126.     }
  127.     else
  128.     if (self.spawnflags & H_MEGA)
  129.     {
  130.         precache_model("maps/b_bh100.bsp");
  131.         precache_sound("items/r_item2.wav");
  132.         setmodel(self, "maps/b_bh100.bsp");
  133.         self.noise = "items/r_item2.wav";
  134.         self.healamount = 100;
  135.         self.healtype = 2;
  136.     }
  137.     else
  138.     {
  139.         precache_model("maps/b_bh25.bsp");
  140.         precache_sound("items/health1.wav");
  141.         setmodel(self, "maps/b_bh25.bsp");
  142.         self.noise = "items/health1.wav";
  143.         self.healamount = 25;
  144.         self.healtype = 1;
  145.     }
  146.     setsize (self, '0 0 0', '32 32 56');
  147.     StartItem ();
  148. };
  149.  
  150.  
  151. void() health_touch =
  152. {
  153.     local   float amount;
  154.     local   string  s;
  155.     
  156.     if (other.classname != "player")
  157.         return;
  158.     
  159.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  160.     {
  161.         if (other.health >= 250)
  162.             return;
  163.         if (!T_Heal(other, self.healamount, 1))
  164.             return;
  165.     }
  166.     else
  167.     {
  168.         if (!T_Heal(other, self.healamount, 0))
  169.             return;
  170.     }
  171.     
  172.     sprint(other, "You receive ");
  173.     s = ftos(self.healamount);
  174.     sprint(other, s);
  175.     sprint(other, " health\n");
  176.     
  177. // health touch sound
  178.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  179.  
  180.     stuffcmd (other, "bf\n");
  181.     
  182.     self.model = string_null;
  183.     self.solid = SOLID_NOT;
  184.  
  185.     // Megahealth = rot down the player's super health
  186.     if (self.healtype == 2)
  187.     {
  188.         other.items = other.items | IT_SUPERHEALTH;
  189.         self.nextthink = time + 5;
  190.         self.think = item_megahealth_rot;
  191.         self.owner = other;
  192.     }
  193.     else
  194.     {
  195.         if (deathmatch != 2)            // deathmatch 2 is the silly old rules
  196.         {
  197.             if (deathmatch)
  198.                 self.nextthink = time + 20;
  199.             self.think = SUB_regen;
  200.         }
  201.     }
  202.     
  203.     activator = other;
  204.     SUB_UseTargets();                               // fire all targets / killtargets
  205. };      
  206.  
  207. void() item_megahealth_rot =
  208. {
  209.     other = self.owner;
  210.     
  211.     if (other.health > other.max_health)
  212.     {
  213.         other.health = other.health - 1;
  214.         self.nextthink = time + 1;
  215.         return;
  216.     }
  217.  
  218. // it is possible for a player to die and respawn between rots, so don't
  219. // just blindly subtract the flag off
  220.     other.items = other.items - (other.items & IT_SUPERHEALTH);
  221.     
  222.     if (deathmatch == 1)    // deathmatch 2 is silly old rules
  223.     {
  224.         self.nextthink = time + 20;
  225.         self.think = SUB_regen;
  226.     }
  227. };
  228.  
  229. /*
  230. ===============================================================================
  231.  
  232. ARMOR
  233.  
  234. ===============================================================================
  235. */
  236.  
  237. void() armor_touch;
  238.  
  239. void() armor_touch =
  240. {
  241.     local   float   type, value, bit;
  242.     
  243.     if (other.health <= 0)
  244.         return;
  245.     if (other.classname != "player")
  246.         return;
  247.  
  248.     if (self.classname == "item_armor1")
  249.     {
  250.         if (other.ishead == 1)
  251.         {
  252.             RestoreBodyB();
  253.         }
  254.         type = 0.3;
  255.         value = 100;
  256.         bit = IT_ARMOR1;
  257.     }
  258.  
  259.     if (other.ishead == 1)
  260.     {
  261.         return;
  262.     }
  263.  
  264.     if (self.classname == "item_armor2")
  265.     {
  266.         type = 0.6;
  267.         value = 150;
  268.         bit = IT_ARMOR2;
  269.     }
  270.     if (self.classname == "item_armorInv")
  271.     {
  272.         type = 0.8;
  273.         value = 200;
  274.         bit = IT_ARMOR3;
  275.     }
  276.     if (other.armortype*other.armorvalue >= type*value)
  277.         return;
  278.             
  279.     other.armortype = type;
  280.     other.armorvalue = value;
  281.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  282.  
  283.     self.solid = SOLID_NOT;
  284.     self.model = string_null;
  285.     if (deathmatch == 1)
  286.         self.nextthink = time + 20;
  287.     self.think = SUB_regen;
  288.  
  289.     sprint(other, "You got armor\n");
  290. // armor touch sound
  291.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  292.     stuffcmd (other, "bf\n");
  293.     
  294.     activator = other;
  295.     SUB_UseTargets();                               // fire all targets / killtargets
  296. };
  297.  
  298.  
  299. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  300. */
  301.  
  302. void() item_armor1 =
  303. {
  304.     self.touch = armor_touch;
  305.     //precache_model ("progs/armor.mdl");
  306.     setmodel (self, "../qjoe/instbody.mdl");
  307.     self.skin = 0;
  308.     setsize (self, '-16 -16 0', '16 16 56');
  309.     StartItem ();
  310. };
  311.  
  312. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  313. */
  314.  
  315. void() item_armor2 =
  316. {
  317.     self.touch = armor_touch;
  318.     precache_model ("progs/armor.mdl");
  319.     setmodel (self, "progs/armor.mdl");
  320.     self.skin = 1;
  321.     setsize (self, '-16 -16 0', '16 16 56');
  322.     StartItem ();
  323. };
  324.  
  325. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  326. */
  327.  
  328. void() item_armorInv =
  329. {
  330.     self.touch = armor_touch;
  331.     precache_model ("progs/armor.mdl");
  332.     setmodel (self, "progs/armor.mdl");
  333.     self.skin = 2;
  334.     setsize (self, '-16 -16 0', '16 16 56');
  335.     StartItem ();
  336. };
  337.  
  338. /*
  339. ===============================================================================
  340.  
  341. WEAPONS
  342.  
  343. ===============================================================================
  344. */
  345.  
  346. void() bound_other_ammo =
  347. {
  348.     if (other.ammo_shells > 100)
  349.         other.ammo_shells = 100;
  350.     if (other.ammo_nails > 200)
  351.         other.ammo_nails = 200;
  352.     if (other.ammo_rockets > 100)
  353.         other.ammo_rockets = 100;               
  354.     if (other.ammo_cells > 100)
  355.         other.ammo_cells = 100;         
  356. };
  357.  
  358.  
  359. float(float w) RankForWeapon =
  360. {
  361.     if (w == IT_LIGHTNING)
  362.         return 1;
  363.     if (w == IT_ROCKET_LAUNCHER)
  364.         return 2;
  365.     if (w == IT_SUPER_NAILGUN)
  366.         return 3;
  367.     if (w == IT_GRENADE_LAUNCHER)
  368.         return 4;
  369.     if (w == IT_SUPER_SHOTGUN)
  370.         return 5;
  371.     if (w == IT_NAILGUN)
  372.         return 6;
  373.     return 7;
  374. };
  375.  
  376. /*
  377. =============
  378. Deathmatch_Weapon
  379.  
  380. Deathmatch weapon change rules for picking up a weapon
  381.  
  382. .float          ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  383. =============
  384. */
  385. void(float old, float new) Deathmatch_Weapon =
  386. {
  387.     local float or, nr;
  388.  
  389. // change self.weapon if desired
  390.     or = RankForWeapon (self.weapon);
  391.     nr = RankForWeapon (new);
  392.     if ( nr < or )
  393.         self.weapon = new;
  394. };
  395.  
  396. /*
  397. =============
  398. weapon_touch
  399. =============
  400. */
  401. float() W_BestWeapon;
  402.  
  403. void() weapon_touch =
  404. {
  405.     local   float   hadammo, best, new, old;
  406.     local   entity  stemp;
  407.     local   float   leave;
  408.  
  409.     if (!(other.flags & FL_CLIENT))
  410.         return;
  411.  
  412.     if (other.ishead == 1)
  413.     {
  414.         //sprint(other, "You Cannot use this, you are a head!");
  415.         return;
  416.     }
  417.  
  418. // if the player was using his best weapon, change up to the new one if better          
  419.     stemp = self;
  420.     self = other;
  421.     best = W_BestWeapon();
  422.     self = stemp;
  423.  
  424.     if (deathmatch == 2 || coop)
  425.         leave = 1;
  426.     else
  427.         leave = 0;
  428.     
  429.     if (self.classname == "weapon_nailgun")
  430.     {
  431.         if (leave && (other.items & IT_NAILGUN) )
  432.             return;
  433.         hadammo = other.ammo_nails;                     
  434.         new = IT_NAILGUN;
  435.         other.ammo_nails = other.ammo_nails + 30;
  436.     }
  437.     else if (self.classname == "weapon_supernailgun")
  438.     {
  439.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  440.             return;
  441.         hadammo = other.ammo_rockets;                   
  442.         new = IT_SUPER_NAILGUN;
  443.         other.ammo_nails = other.ammo_nails + 30;
  444.     }
  445.     else if (self.classname == "weapon_supershotgun")
  446.     {
  447.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  448.             return;
  449.         hadammo = other.ammo_rockets;                   
  450.         new = IT_SUPER_SHOTGUN;
  451.         other.ammo_shells = other.ammo_shells + 5;
  452.     }
  453.     else if (self.classname == "weapon_rocketlauncher")
  454.     {
  455.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  456.             return;
  457.         hadammo = other.ammo_rockets;                   
  458.         new = IT_ROCKET_LAUNCHER;
  459.         other.ammo_rockets = other.ammo_rockets + 5;
  460.     }
  461.     else if (self.classname == "weapon_grenadelauncher")
  462.     {
  463.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  464.             return;
  465.         hadammo = other.ammo_rockets;                   
  466.         new = IT_GRENADE_LAUNCHER;
  467.         other.ammo_rockets = other.ammo_rockets + 5;
  468.     }
  469.     else if (self.classname == "weapon_lightning")
  470.     {
  471.         if (leave && (other.items & IT_LIGHTNING) )
  472.             return;
  473.         hadammo = other.ammo_rockets;                   
  474.         new = IT_LIGHTNING;
  475.         other.ammo_cells = other.ammo_cells + 15;
  476.     }
  477.     else
  478.         objerror ("weapon_touch: unknown classname");
  479.  
  480.     sprint (other, "You got the ");
  481.     sprint (other, self.netname);
  482.     sprint (other, "\n");
  483. // weapon touch sound
  484.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  485.     stuffcmd (other, "bf\n");
  486.  
  487.     bound_other_ammo ();
  488.  
  489. // change to the weapon
  490.     old = other.items;
  491.     other.items = other.items | new;
  492.     
  493.     stemp = self;
  494.     self = other;
  495.  
  496.     if (!deathmatch)
  497.         self.weapon = new;
  498.     else
  499.         Deathmatch_Weapon (old, new);
  500.  
  501.     W_SetCurrentAmmo();
  502.  
  503.     self = stemp;
  504.  
  505.     if (leave)
  506.         return;
  507.  
  508. // remove it in single player, or setup for respawning in deathmatch
  509.     self.model = string_null;
  510.     self.solid = SOLID_NOT;
  511.     if (deathmatch == 1)
  512.         self.nextthink = time + 30;
  513.     self.think = SUB_regen;
  514.     
  515.     activator = other;
  516.     SUB_UseTargets();                               // fire all targets / killtargets
  517. };
  518.  
  519.  
  520. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  521. */
  522.  
  523. void() weapon_supershotgun =
  524. {
  525.     precache_model ("progs/g_shot.mdl");
  526.     setmodel (self, "progs/g_shot.mdl");
  527.     self.weapon = IT_SUPER_SHOTGUN;
  528.     self.netname = "Double-barrelled Shotgun";
  529.     self.touch = weapon_touch;
  530.     setsize (self, '-16 -16 0', '16 16 56');
  531.     StartItem ();
  532. };
  533.  
  534. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  535. */
  536.  
  537. void() weapon_nailgun =
  538. {
  539.     precache_model ("progs/g_nail.mdl");
  540.     setmodel (self, "progs/g_nail.mdl");
  541.     self.weapon = IT_NAILGUN;
  542.     self.netname = "nailgun";
  543.     self.touch = weapon_touch;
  544.     setsize (self, '-16 -16 0', '16 16 56');
  545.     StartItem ();
  546. };
  547.  
  548. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  549. */
  550.  
  551. void() weapon_supernailgun =
  552. {
  553.     precache_model ("progs/g_nail2.mdl");
  554.     setmodel (self, "progs/g_nail2.mdl");
  555.     self.weapon = IT_SUPER_NAILGUN;
  556.     self.netname = "Super Nailgun";
  557.     self.touch = weapon_touch;
  558.     setsize (self, '-16 -16 0', '16 16 56');
  559.     StartItem ();
  560. };
  561.  
  562. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  563. */
  564.  
  565. void() weapon_grenadelauncher =
  566. {
  567.     precache_model ("progs/g_rock.mdl");
  568.     setmodel (self, "progs/g_rock.mdl");
  569.     self.weapon = 3;
  570.     self.netname = "Grenade Launcher";
  571.     self.touch = weapon_touch;
  572.     setsize (self, '-16 -16 0', '16 16 56');
  573.     StartItem ();
  574. };
  575.  
  576. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  577. */
  578.  
  579. void() weapon_rocketlauncher =
  580. {
  581.     precache_model ("progs/g_rock2.mdl");
  582.     setmodel (self, "progs/g_rock2.mdl");
  583.     self.weapon = 3;
  584.     self.netname = "Rocket Launcher";
  585.     self.touch = weapon_touch;
  586.     setsize (self, '-16 -16 0', '16 16 56');
  587.     StartItem ();
  588. };
  589.  
  590.  
  591. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  592. */
  593.  
  594. void() weapon_lightning =
  595. {
  596.     precache_model ("progs/g_light.mdl");
  597.     setmodel (self, "progs/g_light.mdl");
  598.     self.weapon = 3;
  599.     self.netname = "Thunderbolt";
  600.     self.touch = weapon_touch;
  601.     setsize (self, '-16 -16 0', '16 16 56');
  602.     StartItem ();
  603. };
  604.  
  605.  
  606. /*
  607. ===============================================================================
  608.  
  609. AMMO
  610.  
  611. ===============================================================================
  612. */
  613.  
  614. void() ammo_touch =
  615. {
  616. local entity    stemp;
  617. local float             best;
  618.  
  619.     if (other.classname != "player")
  620.         return;
  621.     if (other.health <= 0)
  622.         return;
  623.  
  624.     if (other.ishead == 1)
  625.     {
  626.         //sprint (other, "You cannot use that, you are a head!");
  627.         return;
  628.     }
  629.         
  630. // if the player was using his best weapon, change up to the new one if better          
  631.     stemp = self;
  632.     self = other;
  633.     best = W_BestWeapon();
  634.     self = stemp;
  635.  
  636.  
  637. // shotgun
  638.     if (self.weapon == 1)
  639.     {
  640.         if (other.ammo_shells >= 100)
  641.             return;
  642.         other.ammo_shells = other.ammo_shells + self.aflag;
  643.     }
  644.  
  645. // spikes
  646.     if (self.weapon == 2)
  647.     {
  648.         if (other.ammo_nails >= 200)
  649.             return;
  650.         other.ammo_nails = other.ammo_nails + self.aflag;
  651.     }
  652.  
  653. //      rockets
  654.     if (self.weapon == 3)
  655.     {
  656.         if (other.ammo_rockets >= 100)
  657.             return;
  658.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  659.     }
  660.  
  661. //      cells
  662.     if (self.weapon == 4)
  663.     {
  664.         if (other.ammo_cells >= 200)
  665.             return;
  666.         other.ammo_cells = other.ammo_cells + self.aflag;
  667.     }
  668.  
  669.     bound_other_ammo ();
  670.     
  671.     sprint (other, "You got the ");
  672.     sprint (other, self.netname);
  673.     sprint (other, "\n");
  674. // ammo touch sound
  675.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  676.     stuffcmd (other, "bf\n");
  677.  
  678. // change to a better weapon if appropriate
  679.  
  680.     if ( other.weapon == best )
  681.     {
  682.         stemp = self;
  683.         self = other;
  684.         self.weapon = W_BestWeapon();
  685.         W_SetCurrentAmmo ();
  686.         self = stemp;
  687.     }
  688.  
  689. // if changed current ammo, update it
  690.     stemp = self;
  691.     self = other;
  692.     W_SetCurrentAmmo();
  693.     self = stemp;
  694.  
  695. // remove it in single player, or setup for respawning in deathmatch
  696.     self.model = string_null;
  697.     self.solid = SOLID_NOT;
  698.     if (deathmatch == 1)
  699.         self.nextthink = time + 30;
  700.     
  701.     self.think = SUB_regen;
  702.  
  703.     activator = other;
  704.     SUB_UseTargets();                               // fire all targets / killtargets
  705. };
  706.  
  707.  
  708.  
  709.  
  710. float WEAPON_BIG2 = 1;
  711.  
  712. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  713. */
  714.  
  715. void() item_shells =
  716. {
  717.     self.touch = ammo_touch;
  718.  
  719.     if (self.spawnflags & WEAPON_BIG2)
  720.     {
  721.         precache_model ("maps/b_shell1.bsp");
  722.         setmodel (self, "maps/b_shell1.bsp");
  723.         self.aflag = 40;
  724.     }
  725.     else
  726.     {
  727.         precache_model ("maps/b_shell0.bsp");
  728.         setmodel (self, "maps/b_shell0.bsp");
  729.         self.aflag = 20;
  730.     }
  731.     self.weapon = 1;
  732.     self.netname = "shells";
  733.     setsize (self, '0 0 0', '32 32 56');
  734.     StartItem ();
  735. };
  736.  
  737. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  738. */
  739.  
  740. void() item_spikes =
  741. {
  742.     self.touch = ammo_touch;
  743.  
  744.     if (self.spawnflags & WEAPON_BIG2)
  745.     {
  746.         precache_model ("maps/b_nail1.bsp");
  747.         setmodel (self, "maps/b_nail1.bsp");
  748.         self.aflag = 50;
  749.     }
  750.     else
  751.     {
  752.         precache_model ("maps/b_nail0.bsp");
  753.         setmodel (self, "maps/b_nail0.bsp");
  754.         self.aflag = 25;
  755.     }
  756.     self.weapon = 2;
  757.     self.netname = "nails";
  758.     setsize (self, '0 0 0', '32 32 56');
  759.     StartItem ();
  760. };
  761.  
  762. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  763. */
  764.  
  765. void() item_rockets =
  766. {
  767.     self.touch = ammo_touch;
  768.  
  769.     if (self.spawnflags & WEAPON_BIG2)
  770.     {
  771.         precache_model ("maps/b_rock1.bsp");
  772.         setmodel (self, "maps/b_rock1.bsp");
  773.         self.aflag = 10;
  774.     }
  775.     else
  776.     {
  777.         precache_model ("maps/b_rock0.bsp");
  778.         setmodel (self, "maps/b_rock0.bsp");
  779.         self.aflag = 5;
  780.     }
  781.     self.weapon = 3;
  782.     self.netname = "rockets";
  783.     setsize (self, '0 0 0', '32 32 56');
  784.     StartItem ();
  785. };
  786.  
  787.  
  788. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  789. */
  790.  
  791. void() item_cells =
  792. {
  793.     self.touch = ammo_touch;
  794.  
  795.     if (self.spawnflags & WEAPON_BIG2)
  796.     {
  797.         precache_model ("maps/b_batt1.bsp");
  798.         setmodel (self, "maps/b_batt1.bsp");
  799.         self.aflag = 12;
  800.     }
  801.     else
  802.     {
  803.         precache_model ("maps/b_batt0.bsp");
  804.         setmodel (self, "maps/b_batt0.bsp");
  805.         self.aflag = 6;
  806.     }
  807.     self.weapon = 4;
  808.     self.netname = "cells";
  809.     setsize (self, '0 0 0', '32 32 56');
  810.     StartItem ();
  811. };
  812.  
  813.  
  814. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  815. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  816. */
  817.  
  818. float WEAPON_SHOTGUN = 1;
  819. float WEAPON_ROCKET = 2;
  820. float WEAPON_SPIKES = 4;
  821. float WEAPON_BIG = 8;
  822. void() item_weapon =
  823. {
  824.     self.touch = ammo_touch;
  825.  
  826.     if (self.spawnflags & WEAPON_SHOTGUN)
  827.     {
  828.         if (self.spawnflags & WEAPON_BIG)
  829.         {
  830.             precache_model ("maps/b_shell1.bsp");
  831.             setmodel (self, "maps/b_shell1.bsp");
  832.             self.aflag = 40;
  833.         }
  834.         else
  835.         {
  836.             precache_model ("maps/b_shell0.bsp");
  837.             setmodel (self, "maps/b_shell0.bsp");
  838.             self.aflag = 20;
  839.         }
  840.         self.weapon = 1;
  841.         self.netname = "shells";
  842.     }
  843.  
  844.     if (self.spawnflags & WEAPON_SPIKES)
  845.     {
  846.         if (self.spawnflags & WEAPON_BIG)
  847.         {
  848.             precache_model ("maps/b_nail1.bsp");
  849.             setmodel (self, "maps/b_nail1.bsp");
  850.             self.aflag = 40;
  851.         }
  852.         else
  853.         {
  854.             precache_model ("maps/b_nail0.bsp");
  855.             setmodel (self, "maps/b_nail0.bsp");
  856.             self.aflag = 20;
  857.         }
  858.         self.weapon = 2;
  859.         self.netname = "spikes";
  860.     }
  861.  
  862.     if (self.spawnflags & WEAPON_ROCKET)
  863.     {
  864.         if (self.spawnflags & WEAPON_BIG)
  865.         {
  866.             precache_model ("maps/b_rock1.bsp");
  867.             setmodel (self, "maps/b_rock1.bsp");
  868.             self.aflag = 10;
  869.         }
  870.         else
  871.         {
  872.             precache_model ("maps/b_rock0.bsp");
  873.             setmodel (self, "maps/b_rock0.bsp");
  874.             self.aflag = 5;
  875.         }
  876.         self.weapon = 3;
  877.         self.netname = "rockets";
  878.     }
  879.     
  880.     setsize (self, '0 0 0', '32 32 56');
  881.     StartItem ();
  882. };
  883.  
  884.  
  885. /*
  886. ===============================================================================
  887.  
  888. KEYS
  889.  
  890. ===============================================================================
  891. */
  892.  
  893. void() key_touch =
  894. {
  895. local entity    stemp;
  896. local float             best;
  897.  
  898.     if (other.classname != "player")
  899.         return;
  900.     if (other.health <= 0)
  901.         return;
  902.     if (other.items & self.items)
  903.         return;
  904.  
  905.     sprint (other, "You got the ");
  906.     sprint (other, self.netname);
  907.     sprint (other,"\n");
  908.  
  909.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  910.     stuffcmd (other, "bf\n");
  911.     other.items = other.items | self.items;
  912.  
  913.     if (!coop)
  914.     {       
  915.         self.solid = SOLID_NOT;
  916.         self.model = string_null;
  917.     }
  918.  
  919.     activator = other;
  920.     SUB_UseTargets();                               // fire all targets / killtargets
  921. };
  922.  
  923.  
  924. void() key_setsounds =
  925. {
  926.     if (world.worldtype == 0)
  927.     {
  928.         precache_sound ("misc/medkey.wav");
  929.         self.noise = "misc/medkey.wav";
  930.     }
  931.     if (world.worldtype == 1)
  932.     {
  933.         precache_sound ("misc/runekey.wav");
  934.         self.noise = "misc/runekey.wav";
  935.     }
  936.     if (world.worldtype == 2)
  937.     {
  938.         precache_sound2 ("misc/basekey.wav");
  939.         self.noise = "misc/basekey.wav";
  940.     }
  941. };
  942.  
  943. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  944. SILVER key
  945. In order for keys to work
  946. you MUST set your maps
  947. worldtype to one of the
  948. following:
  949. 0: medieval
  950. 1: metal
  951. 2: base
  952. */
  953.  
  954. void() item_key1 =
  955. {
  956.     if (world.worldtype == 0)
  957.     {
  958.         precache_model ("progs/w_s_key.mdl");
  959.         setmodel (self, "progs/w_s_key.mdl");
  960.         self.netname = "silver key";
  961.     }
  962.     else if (world.worldtype == 1)
  963.     {
  964.         precache_model ("progs/m_s_key.mdl");
  965.         setmodel (self, "progs/m_s_key.mdl");
  966.         self.netname = "silver runekey";
  967.     }
  968.     else if (world.worldtype == 2)
  969.     {
  970.         precache_model2 ("progs/b_s_key.mdl");
  971.         setmodel (self, "progs/b_s_key.mdl");
  972.         self.netname = "silver keycard";
  973.     }
  974.     key_setsounds();
  975.     self.touch = key_touch;
  976.     self.items = IT_KEY1;
  977.     setsize (self, '-16 -16 -24', '16 16 32');
  978.     StartItem ();
  979. };
  980.  
  981. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  982. GOLD key
  983. In order for keys to work
  984. you MUST set your maps
  985. worldtype to one of the
  986. following:
  987. 0: medieval
  988. 1: metal
  989. 2: base
  990. */
  991.  
  992. void() item_key2 =
  993. {
  994.     if (world.worldtype == 0)
  995.     {
  996.         precache_model ("progs/w_g_key.mdl");
  997.         setmodel (self, "progs/w_g_key.mdl");
  998.         self.netname = "gold key";
  999.     }
  1000.     if (world.worldtype == 1)
  1001.     {
  1002.         precache_model ("progs/m_g_key.mdl");
  1003.         setmodel (self, "progs/m_g_key.mdl");
  1004.         self.netname = "gold runekey";
  1005.     }
  1006.     if (world.worldtype == 2)
  1007.     {
  1008.         precache_model2 ("progs/b_g_key.mdl");
  1009.         setmodel (self, "progs/b_g_key.mdl");
  1010.         self.netname = "gold keycard";
  1011.     }
  1012.     key_setsounds();
  1013.     self.touch = key_touch;
  1014.     self.items = IT_KEY2;
  1015.     setsize (self, '-16 -16 -24', '16 16 32');
  1016.     StartItem ();
  1017. };
  1018.  
  1019.  
  1020.  
  1021. /*
  1022. ===============================================================================
  1023.  
  1024. END OF LEVEL RUNES
  1025.  
  1026. ===============================================================================
  1027. */
  1028.  
  1029. void() sigil_touch =
  1030. {
  1031. local entity    stemp;
  1032. local float             best;
  1033.  
  1034.     if (other.classname != "player")
  1035.         return;
  1036.     if (other.health <= 0)
  1037.         return;
  1038.  
  1039.     centerprint (other, "You got the rune!");
  1040.  
  1041.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1042.     stuffcmd (other, "bf\n");
  1043.     self.solid = SOLID_NOT;
  1044.     self.model = string_null;
  1045.     serverflags = serverflags | (self.spawnflags & 15);
  1046.     self.classname = "";            // so rune doors won't find it
  1047.     
  1048.     activator = other;
  1049.     SUB_UseTargets();                               // fire all targets / killtargets
  1050. };
  1051.  
  1052.  
  1053. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1054. End of level sigil, pick up to end episode and return to jrstart.
  1055. */
  1056.  
  1057. void() item_sigil =
  1058. {
  1059.     if (!self.spawnflags)
  1060.         objerror ("no spawnflags");
  1061.  
  1062.     precache_sound ("misc/runekey.wav");
  1063.     self.noise = "misc/runekey.wav";
  1064.  
  1065.     if (self.spawnflags & 1)
  1066.     {
  1067.         precache_model ("progs/end1.mdl");
  1068.         setmodel (self, "progs/end1.mdl");
  1069.     }
  1070.     if (self.spawnflags & 2)
  1071.     {
  1072.         precache_model2 ("progs/end2.mdl");
  1073.         setmodel (self, "progs/end2.mdl");
  1074.     }
  1075.     if (self.spawnflags & 4)
  1076.     {
  1077.         precache_model2 ("progs/end3.mdl");
  1078.         setmodel (self, "progs/end3.mdl");
  1079.     }
  1080.     if (self.spawnflags & 8)
  1081.     {
  1082.         precache_model2 ("progs/end4.mdl");
  1083.         setmodel (self, "progs/end4.mdl");
  1084.     }
  1085.     
  1086.     self.touch = sigil_touch;
  1087.     setsize (self, '-16 -16 -24', '16 16 32');
  1088.     StartItem ();
  1089. };
  1090.  
  1091. /*
  1092. ===============================================================================
  1093.  
  1094. POWERUPS
  1095.  
  1096. ===============================================================================
  1097. */
  1098.  
  1099. void() powerup_touch;
  1100.  
  1101.  
  1102. void() powerup_touch =
  1103. {
  1104. local entity    stemp;
  1105. local float             best;
  1106.  
  1107.     if (other.classname != "player")
  1108.         return;
  1109.     if (other.health <= 0)
  1110.         return;
  1111.  
  1112.     sprint (other, "You got the ");
  1113.     sprint (other, self.netname);
  1114.     sprint (other,"\n");
  1115.  
  1116.     if (deathmatch)
  1117.     {
  1118.         self.mdl = self.model;
  1119.         
  1120.         if ((self.classname == "item_artifact_invulnerability") ||
  1121.             (self.classname == "item_artifact_invisibility"))
  1122.             self.nextthink = time + 60*5;
  1123.         else
  1124.             self.nextthink = time + 60;
  1125.         
  1126.         self.think = SUB_regen;
  1127.     }       
  1128.  
  1129.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1130.     stuffcmd (other, "bf\n");
  1131.     self.solid = SOLID_NOT;
  1132.     other.items = other.items | self.items;
  1133.     self.model = string_null;
  1134.  
  1135. // do the apropriate action
  1136.     if (self.classname == "item_artifact_envirosuit")
  1137.     {
  1138.         if (other.ishead != 1)
  1139.         {
  1140.         other.rad_time = 1;
  1141.         other.radsuit_finished = time + 30;
  1142.         }
  1143.         else
  1144.         {
  1145.         //sprint (other, "You cannot use this, you are a head!");
  1146.         return;
  1147.         }
  1148.     }
  1149.     
  1150.     if (self.classname == "item_artifact_invulnerability")
  1151.     {
  1152.         other.invincible_time = 1;
  1153.         other.invincible_finished = time + 30;
  1154.     }
  1155.     
  1156.     if (self.classname == "item_artifact_invisibility")
  1157.     {
  1158.         if (other.ishead != 1)
  1159.         {
  1160.         other.invisible_time = 1;
  1161.         other.invisible_finished = time + 30;
  1162.         }
  1163.         else
  1164.         {
  1165.         //sprint (other, "You cannot use this, you are a head!");
  1166.         return;
  1167.         }
  1168.  
  1169.     }
  1170.  
  1171.     if (self.classname == "item_artifact_super_damage")
  1172.     {
  1173.         other.super_time = 1;
  1174.         other.super_damage_finished = time + 30;
  1175.     }       
  1176.  
  1177.     activator = other;
  1178.     SUB_UseTargets();                               // fire all targets / killtargets
  1179. };
  1180.  
  1181.  
  1182.  
  1183. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1184. Player is invulnerable for 30 seconds
  1185. */
  1186. void() item_artifact_invulnerability =
  1187. {
  1188.     self.touch = powerup_touch;
  1189.  
  1190.     precache_model ("progs/invulner.mdl");
  1191.     precache_sound ("items/protect.wav");
  1192.     precache_sound ("items/protect2.wav");
  1193.     precache_sound ("items/protect3.wav");
  1194.     self.noise = "items/protect.wav";
  1195.     setmodel (self, "progs/invulner.mdl");
  1196.     self.netname = "Pentagram of Protection";
  1197.     self.items = IT_INVULNERABILITY;
  1198.     setsize (self, '-16 -16 -24', '16 16 32');
  1199.     StartItem ();
  1200. };
  1201.  
  1202. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1203. Player takes no damage from water or slime for 30 seconds
  1204. */
  1205. void() item_artifact_envirosuit =
  1206. {
  1207.     self.touch = powerup_touch;
  1208.  
  1209.     precache_model ("progs/suit.mdl");
  1210.     precache_sound ("items/suit.wav");
  1211.     precache_sound ("items/suit2.wav");
  1212.     self.noise = "items/suit.wav";
  1213.     setmodel (self, "progs/suit.mdl");
  1214.     self.netname = "Biosuit";
  1215.     self.items = IT_SUIT;
  1216.     setsize (self, '-16 -16 -24', '16 16 32');
  1217.     StartItem ();
  1218. };
  1219.  
  1220.  
  1221. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1222. Player is invisible for 30 seconds
  1223. */
  1224. void() item_artifact_invisibility =
  1225. {
  1226.     self.touch = powerup_touch;
  1227.  
  1228.     precache_model ("progs/invisibl.mdl");
  1229.     precache_sound ("items/inv1.wav");
  1230.     precache_sound ("items/inv2.wav");
  1231.     precache_sound ("items/inv3.wav");
  1232.     self.noise = "items/inv1.wav";
  1233.     setmodel (self, "progs/invisibl.mdl");
  1234.     self.netname = "Ring of Shadows";
  1235.     self.items = IT_INVISIBILITY;
  1236.     setsize (self, '-16 -16 -24', '16 16 32');
  1237.     StartItem ();
  1238. };
  1239.  
  1240.  
  1241. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1242. The next attack from the player will do 4x damage
  1243. */
  1244. void() item_artifact_super_damage =
  1245. {
  1246.     self.touch = powerup_touch;
  1247.  
  1248.     precache_model ("progs/quaddama.mdl");
  1249.     precache_sound ("items/damage.wav");
  1250.     precache_sound ("items/damage2.wav");
  1251.     precache_sound ("items/damage3.wav");
  1252.     self.noise = "items/damage.wav";
  1253.     setmodel (self, "progs/quaddama.mdl");
  1254.     self.netname = "Quad Damage";
  1255.     self.items = IT_QUAD;
  1256.     setsize (self, '-16 -16 -24', '16 16 32');
  1257.     StartItem ();
  1258. };
  1259.  
  1260.  
  1261.  
  1262. /*
  1263. ===============================================================================
  1264.  
  1265. PLAYER BACKPACKS
  1266.  
  1267. ===============================================================================
  1268. */
  1269.  
  1270. void() BackpackTouch =
  1271. {
  1272.     local string    s;
  1273.     local   float   best;
  1274.     local           entity  stemp;
  1275.     
  1276.     if (other.classname != "player")
  1277.         return;
  1278.     if (other.health <= 0)
  1279.         return;
  1280.         
  1281.     if (other.ishead == 1)
  1282.     {
  1283.         //sprint (other, "You cannot use this, you are a head!");
  1284.         return;
  1285.     }
  1286. // if the player was using his best weapon, change up to the new one if better          
  1287.     stemp = self;
  1288.     self = other;
  1289.     best = W_BestWeapon();
  1290.     self = stemp;
  1291.  
  1292. // change weapons
  1293.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1294.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1295.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1296.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1297.  
  1298.     other.items = other.items | self.items;
  1299.     
  1300.     bound_other_ammo ();
  1301.  
  1302.     sprint (other, "You get ");
  1303.  
  1304.     if (self.ammo_shells)
  1305.     {
  1306.         s = ftos(self.ammo_shells);
  1307.         sprint (other, s);
  1308.         sprint (other, " shells  ");
  1309.     }
  1310.     if (self.ammo_nails)
  1311.     {
  1312.         s = ftos(self.ammo_nails);
  1313.         sprint (other, s);
  1314.         sprint (other, " nails ");
  1315.     }
  1316.     if (self.ammo_rockets)
  1317.     {
  1318.         s = ftos(self.ammo_rockets);
  1319.         sprint (other, s);
  1320.         sprint (other, " rockets  ");
  1321.     }
  1322.     if (self.ammo_cells)
  1323.     {
  1324.         s = ftos(self.ammo_cells);
  1325.         sprint (other, s);
  1326.         sprint (other, " cells  ");
  1327.     }
  1328.     
  1329.     sprint (other, "\n");
  1330. // backpack touch sound
  1331.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1332.     stuffcmd (other, "bf\n");
  1333.  
  1334. // change to a better weapon if appropriate
  1335.     if ( other.weapon == best )
  1336.     {
  1337.         stemp = self;
  1338.         self = other;
  1339.         self.weapon = W_BestWeapon();
  1340.         self = stemp;
  1341.     }
  1342.  
  1343.     
  1344.     remove(self);
  1345.     
  1346.     self = other;
  1347.     W_SetCurrentAmmo ();
  1348. };
  1349.  
  1350. /*
  1351. ===============
  1352. DropBackpack
  1353. ===============
  1354. */
  1355. void() DropBackpack =
  1356. {
  1357.     local entity    item;
  1358.  
  1359.     if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1360.         return; // nothing in it
  1361.  
  1362.     item = spawn();
  1363.     item.origin = self.origin - '0 0 24';
  1364.     
  1365.     item.items = self.weapon;
  1366.  
  1367.     item.ammo_shells = self.ammo_shells;
  1368.     item.ammo_nails = self.ammo_nails;
  1369.     item.ammo_rockets = self.ammo_rockets;
  1370.     item.ammo_cells = self.ammo_cells;
  1371.  
  1372.     item.velocity_z = 300;
  1373.     item.velocity_x = -100 + (random() * 200);
  1374.     item.velocity_y = -100 + (random() * 200);
  1375.     
  1376.     item.flags = FL_ITEM;
  1377.     item.solid = SOLID_TRIGGER;
  1378.     item.movetype = MOVETYPE_TOSS;
  1379.     setmodel (item, "progs/backpack.mdl");
  1380.     setsize (item, '-16 -16 0', '16 16 56');
  1381.     item.touch = BackpackTouch;
  1382.     
  1383.     item.nextthink = time + 120;    // remove after 2 minutes
  1384.     item.think = SUB_Remove;
  1385. };
  1386.